package com.cheetah.support;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author Administrator
 * @Date 2019/10/9
 * @Version V1.0
 * @Description: 自定义读取yaml配置文件做解析对应key的配置项,目前只解析spring.config.location属性对应配置项，所以必须配置此属性
 * 例如：Mongo、Redis配置项 @See Mongo
 **/
@Slf4j
public class ConfigHandler<T> {

    public static final String DOT = "\\.";
    private Map<String,T> result = new HashMap<>();

    public Map<String,T> handleConfig(Map<String, LinkedHashMap> map, String name, Class<T> clazz){
        String[] names = name.split(DOT);
        String key = names[0];
        if(names.length > 1){
            LinkedHashMap linkedHashMap = map.get(key);
            if(linkedHashMap == null){
                return result;
            }
            return handleConfig(linkedHashMap,name.replaceFirst(key + DOT,""),clazz);
        }else {
            LinkedHashMap linkedHashMap = map.get(key);
            ObjectMapper mapper = new ObjectMapper();
            try {
                String json = mapper.writeValueAsString(linkedHashMap);
                Map<String,Map> tmpMap = mapper.readValue(json, HashMap.class);
                tmpMap.forEach((k,v) -> {
                    try {
                        String j = mapper.writeValueAsString(v);
                        T t = mapper.readValue(j,clazz);
                        result.put(k,t);
                    } catch (IOException e) {
                        log.error(e.getMessage(),e);
                    }
                });
                return result;
            } catch (IOException e) {
                log.error(e.getMessage(),e);
            }
        }
        return result;
    }
//
//    /**
//     * apollo发布属性时更新配置项，此种情况是在非spring初始化配置项的时候适用，spring初始化的配置自动更新，无需监听
//     * @param configMap
//     * @param keyPre
//     * @param changeEvent
//     * @return
//     */
//    public Map<String,T> handleConfigOnChange(Map<String, T> configMap, String keyPre, ConfigChangeEvent changeEvent,Class<T> clazz){
//        Set<String> configKeys = new HashSet<>();
//        for (String key : changeEvent.changedKeys()){
//            configKeys.add(key.replaceFirst(keyPre + DOT,"").split(DOT)[0]);
//        }
//        ObjectMapper mapper = new ObjectMapper();
//
//        Map<String,T> _configMap = new HashMap<>();
//        for(String key : configKeys){
//            Map<String,String> configChanged = new HashMap<>();
//            Iterator<String> it = changeEvent.changedKeys().iterator();
//            while (it.hasNext()){
//                String k = it.next();
//                if(k.startsWith(keyPre + "." + key)){
//                    configChanged.put(k.replaceFirst(keyPre + DOT + key + DOT,"")
//                            ,changeEvent.getChange(k).getNewValue());
//                }
//            }
//
//            try {
//                String j = mapper.writeValueAsString(configChanged);
//                T tNew = mapper.readValue(j,clazz);
//                T tOld = configMap.get(key);
//
//                BeanUtils.copyProperties(tNew,tOld);
//
//                _configMap.put(key,tOld);
//            } catch (IOException e) {
//                log.error(e.getMessage(),e);
//            }
//        }
//
//        return _configMap;
//    }
//
//    public Map<String,T> getConfigFromApollo(Config apolloConfig,String name,Class<T> clazz) {
//        Set<String> set = apolloConfig.getPropertyNames();
//
//        Set<String> database = new HashSet<>();
//        set.stream().filter(k -> k.startsWith(name)).forEach(k -> {
//            database.add(k.replaceFirst(name,"").split("\\.")[0]);
//        });
//
//        ObjectMapper mapper = new ObjectMapper();
//        Map<String,T> config = new HashMap<>();
//        database.stream().forEach(k -> {
//            Map map = new HashMap();
//            set.stream().filter(m -> m.startsWith(name + k)).forEach(m ->{
//                map.put(m.replaceFirst(name + k + "\\.",""),apolloConfig.getProperty(m,null));
//            });
//
//            String j = null;
//            try {
//                if(map.size() == 0)
//                    return;
//                j = mapper.writeValueAsString(map);
//                T t = mapper.readValue(j,clazz);
//                config.put(k,t);
//            } catch (IOException e) {
//                log.error(e.getMessage(),e);
//            }
//
//        });
//
//        return config;
////        addApolloListener(apolloConfig);
//    }
}
